package screens
{
	import events.NavigationEvent;
	
	import flash.geom.Rectangle;
	import flash.utils.getTimer;
	
	import flashx.textLayout.elements.ParagraphElement;
	
	import objects.GameBackground;
	import objects.Hero;
	import objects.Item;
	import objects.Obstacle;
	import objects.Particle;
	
	import starling.display.Button;
	import starling.display.Sprite;
	import starling.events.Event;
	import starling.events.Touch;
	import starling.events.TouchEvent;
	import starling.text.TextField;
	import starling.utils.HAlign;
	import starling.utils.VAlign;
	import starling.utils.deg2rad;
	
	public class InGame extends Sprite
	{
		private var startButton:Button;
		private var bg:GameBackground;
		private var hero:Hero;
		
		private var timePrevious:Number;
		private var timeCurrent:Number;
		private var elapsed:Number;
		
		private var gameState:String;
		private var playerSpeed:Number;
		private var hitObstacle:Number = 0;
		private const MIN_SPEED:Number = 650;
		
		private var scoreDistance:int;
		private var obstacleGapCount:int;
		
		private var gameArea:Rectangle;
		
		private var touch:Touch;
		private var touchX:Number;
		private var touchY:Number;
		
		private var obstaclesToAnimate:Vector.<Obstacle>;
		private var itemToAnimate:Vector.<Item>;
		private var eatParticleToAnimate:Vector.<Particle>;
		
		private var scoreText:TextField;
		private var liftText:TextField;
		private var scoreEat:uint;
		private var lifeNum:uint;
		public function InGame()
		{
			super();
			this.addEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);
		}
		
		private function onAddedToStage(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			drawGame();
		}
		/**
		 *绘制界面 
		 * 
		 */		
		private function drawGame():void
		{
			bg = new GameBackground();
			this.addChild(bg);
			
			hero = new Hero();
			hero.x = stage.stageWidth/2;
			hero.y = stage.stageHeight/2;
			this.addChild(hero);
			
			startButton = new Button(Assets.getAtlas().getTexture("startButton"));
			startButton.x = stage.stageWidth * 0.5 - startButton.width * 0.5;
			startButton.y = stage.stageHeight * 0.5 - startButton.height * 0.5;
			this.addChild(startButton);
			
			scoreText = new TextField(200,100,"SCORE:0",Assets.getFont().name,24,0xffffff);
			this.addChild(scoreText);
			scoreText.vAlign = VAlign.TOP;
			scoreText.hAlign = HAlign.LEFT;
			scoreText.y = 20;
			scoreText.height = scoreText.textBounds.height+10;
			scoreText.x = 580;
			liftText = new TextField(200,100,"LIFE:3",Assets.getFont().name,24,0xffffff);
			this.addChild(liftText);
			liftText.vAlign = VAlign.TOP;
			liftText.hAlign = HAlign.LEFT;
			liftText.y = 20;
			liftText.height = scoreText.textBounds.height+10;
			liftText.x = 380;
			
			gameArea = new Rectangle(0, 50, stage.stageWidth, stage.stageHeight - 150);
		}
		/**
		 *清理 
		 * 
		 */		
		public function disposeTemporarily():void
		{
			this.visible = false;
			if(eatParticleToAnimate){
				
				for (var i:int = 0; i < eatParticleToAnimate.length; i++) 
				{
					this.removeChild(eatParticleToAnimate[i]);
				}
				for (var j:int = 0; j < itemToAnimate.length; j++) 
				{
					this.removeChild(itemToAnimate[j]);
				}
				for (var k:int = 0; k < obstaclesToAnimate.length; k++) 
				{
					this.removeChild(obstaclesToAnimate[k]);
				}
				this.removeEventListener(Event.ENTER_FRAME, onGameTick);
				this.removeEventListener(Event.ENTER_FRAME, checkElapsed);
			}
			
			
			
		}
		/**
		 *初始化 
		 * 
		 */		
		public function initialize():void
		{
			this.visible = true;
			this.startButton.visible = true;
			
			this.addEventListener(Event.ENTER_FRAME, checkElapsed);
			
			hero.x = -stage.stageWidth;
			hero.y = stage.stageHeight * 0.5;
			
			gameState = "idle";
			
			playerSpeed = 0;
			hitObstacle = 0;
			
			bg.speed = 0;
			scoreDistance = 0;
			obstacleGapCount = 0;
			
			lifeNum = 5;
			scoreEat = 0;
			scoreText.text = "SCORE: "+scoreEat;
			liftText.text = "LIFE: "+lifeNum;
			
			
			obstaclesToAnimate = new Vector.<Obstacle>();
			itemToAnimate = new Vector.<Item>();
			eatParticleToAnimate = new Vector.<Particle>();
			startButton.addEventListener(Event.TRIGGERED, onStartButtonClick);
		}
		/**
		 *开始 
		 * @param event
		 * 
		 */		
		private function onStartButtonClick(event:Event):void
		{
			startButton.visible = false;
			startButton.removeEventListener(Event.TRIGGERED, onStartButtonClick);
			
			launchHero();
		}
		/**
		 *加载英雄 
		 * 
		 */		
		private function launchHero():void
		{
			this.addEventListener(TouchEvent.TOUCH, onTouch);
			this.addEventListener(Event.ENTER_FRAME, onGameTick);
		}
		/**
		 *触摸屏幕 
		 * @param event
		 * 
		 */		
		private function onTouch(event:TouchEvent):void
		{
			touch = event.getTouch(stage);
			
			touchX = touch.globalX;
			touchY = touch.globalY;
		}
		/**
		 * 游戏心跳函数
		 * @param event
		 * 
		 */		
		private function onGameTick(event:Event):void
		{
			switch(gameState)
			{
				case "idle"://空闲--英雄飞入
					if (hero.x < stage.stageWidth * 0.5 * 0.5)
					{
						hero.x += ((stage.stageWidth * 0.5 * 0.5 + 10) - hero.x) * 0.05;
						hero.y = stage.stageHeight * 0.5;
						
						playerSpeed += (MIN_SPEED - playerSpeed) * 0.05;
						bg.speed = playerSpeed * elapsed;
					}
					else
					{
						gameState = "flying";
					}
					break;
				case "flying"://英雄飞行过程
					
					if (hitObstacle <= 0)
					{
						hero.y -= (hero.y - touchY) * 0.1;
						
						if (-(hero.y - touchY) < 150 && -(hero.y - touchY) > -150)
						{
							hero.rotation = deg2rad(-(hero.y - touchY) * 0.2);
						}
						
						if (hero.y > gameArea.bottom - hero.height * 0.5)
						{
							hero.y = gameArea.bottom - hero.height * 0.5;
							hero.rotation = deg2rad(0);
						}
						if (hero.y < gameArea.top + hero.height * 0.5)
						{
							hero.y = gameArea.top + hero.height * 0.5;
							hero.rotation = deg2rad(0);
						}
					}
					else
					{
						hitObstacle--;
						cameraShake();
					}
					
					playerSpeed -= (playerSpeed - MIN_SPEED) * 0.01;
					bg.speed = playerSpeed * elapsed;
					
					scoreDistance += (playerSpeed * elapsed) * 0.1;
					
					initObstacle();
					animateObstacles();
					
					creatFoodItem();
					animateItem();
					animateEatParticle();
					break;
				case "over":
					this.dispatchEvent(new NavigationEvent(NavigationEvent.CHANGE_SCREEN,{id:"over",score:scoreEat},true));
					break;
			}
		}
		/**
		 *播放吃食物时的动画 
		 * 
		 */		
		private function animateEatParticle():void
		{
			for (var i:int = 0; i < eatParticleToAnimate.length; i++) 
			{
				var eatParticleToTrack:Particle = eatParticleToAnimate[i];
				if(eatParticleToTrack){
					eatParticleToTrack.scaleX -=0.03;
					eatParticleToTrack.scaleY = eatParticleToTrack.scaleX;
					
					eatParticleToTrack.y -= eatParticleToTrack.speedY;
					eatParticleToTrack.scaleY -= eatParticleToTrack.speedY * 0.1;
					
					eatParticleToTrack.x += eatParticleToTrack.speedX;
					eatParticleToTrack.speedX--;
					
					eatParticleToTrack.rotation += deg2rad(eatParticleToTrack.spin);
					eatParticleToTrack.spin *=1.1;
					
					if(eatParticleToTrack.scaleY <=0.02){
						eatParticleToAnimate.splice(i,1);
						this.removeChild(eatParticleToTrack);
						eatParticleToTrack = null;
					}
				}
			}
			
		}
		/**
		 *运动Item 
		 * 
		 */		
		private function animateItem():void
		{
			var itemToTrack:Item;
			for (var i:int = 0; i < itemToAnimate.length; i++) 
			{
				itemToTrack = itemToAnimate[i];
				itemToTrack.x -= playerSpeed * elapsed;
				
				if(itemToTrack.bounds.intersects(hero.bounds))
				{
					creatEatParticle(itemToTrack);
					
					
					scoreEat++;
					scoreText.text = "SCORE: "+scoreEat;
					
					GameSound.getInstance().playEat();
					
					itemToAnimate.splice(i,1);
					this.removeChild(itemToTrack);
				}
				
				if(itemToTrack.x < -50){
					itemToAnimate.splice(i,1);
					this.removeChild(itemToTrack);
				}
				
			}
			
		}
		/**
		 *创建吃食物的动画 
		 * @param itemToTrack
		 * 
		 */		
		private function creatEatParticle(itemToTrack:Item):void
		{
			var count:int=5;
			
			while (count>0)
			{
				count--;
				
				var eatParticle:Particle = new Particle();
				this.addChild(eatParticle);
				
				eatParticle.x = itemToTrack.x + Math.random()*40 - 20;
				eatParticle.y = itemToTrack.y - Math.random()*40;
				
				eatParticle.speedX = Math.random() * 2+1;
				eatParticle.speedY = Math.random() * 5;
				eatParticle.spin = Math.random() * 15;
				
				eatParticle.scaleX = eatParticle.scaleY = Math.random()*0.3+0.3;
				
				eatParticleToAnimate.push(eatParticle);
			}
			
		}
		/**
		 *创建食物Item 
		 * 
		 */		
		private function creatFoodItem():void
		{
			if(Math.random()>0.95){
				var itemToTrack:Item = new Item(Math.ceil(Math.random()*5));
				itemToTrack.x = stage.stageWidth+50;
				itemToTrack.y = int(Math.random() * gameArea.height)+gameArea.top;
				this.addChild(itemToTrack);
				itemToAnimate.push(itemToTrack);
			}
		}
		
		private function cameraShake():void
		{
			if (hitObstacle > 0)
			{
				this.x = int(Math.random() * hitObstacle);
				this.y = int(Math.random() * hitObstacle);
			}
			else if (x != 0)
			{
				this.x = 0;
				this.y = 0;
			}
		}
		
		private function animateObstacles():void
		{
			var obstacleToTrack:Obstacle;
			
			for (var i:uint = 0;i<obstaclesToAnimate.length;i++)
			{
				obstacleToTrack = obstaclesToAnimate[i];
				
				if (obstacleToTrack.alreadyHit == false && obstacleToTrack.bounds.intersects(hero.bounds))
				{
					obstacleToTrack.alreadyHit = true;
					obstacleToTrack.rotation = deg2rad(70);
					hitObstacle = 30;
					playerSpeed *= 0.5;
					
					lifeNum--;
					liftText.text = "LIFE: "+lifeNum;
					GameSound.getInstance().playHit();
					if(lifeNum<=0){
						gameState ="over";
					}
				}
				
				if (obstacleToTrack.distance > 0)
				{
					obstacleToTrack.distance -= playerSpeed * elapsed;
				}
				else
				{
					if (obstacleToTrack.watchOut)
					{
						obstacleToTrack.watchOut = false;
					}
					obstacleToTrack.x -= (playerSpeed + obstacleToTrack.speed) * elapsed;
				}
				
				if (obstacleToTrack.x < -obstacleToTrack.width || gameState == "over")
				{
					obstaclesToAnimate.splice(i, 1);
					this.removeChild(obstacleToTrack);
				}
			}
		}
		/**
		 *初始化障碍物 
		 * 
		 */		
		private function initObstacle():void
		{
			if (obstacleGapCount < 1200)
			{
				obstacleGapCount += playerSpeed * elapsed;
			}
			else if (obstacleGapCount != 0)
			{
				obstacleGapCount = 0;
				createObstacle(Math.ceil(Math.random() * 4), Math.random() * 1000 + 1000);
			}
		}
		/**
		 *创建障碍物 
		 * @param type
		 * @param distance
		 * 
		 */		
		private function createObstacle(type:Number, distance:Number):void
		{
			var obstacle:Obstacle = new Obstacle(type, distance, true, 300);
			obstacle.x = stage.stageWidth;
			this.addChild(obstacle);
			
			if (type <= 3)
			{
				if (Math.random() > 0.5)
				{
					obstacle.y = gameArea.top;
					obstacle.position = "top";
				}
				else
				{
					obstacle.y = gameArea.bottom - obstacle.height;
					obstacle.position = "bottom";
				}
			}
			else
			{
				obstacle.y = int(Math.random() * (gameArea.bottom - obstacle.height - gameArea.top)) + gameArea.top;
				obstacle.position = "middle";
			}
			obstaclesToAnimate.push(obstacle);
		}
		/**
		 *检查时间间隔 
		 * @param event
		 * 
		 */		
		private function checkElapsed(event:Event):void
		{
			timePrevious = timeCurrent;
			timeCurrent = getTimer();
			elapsed = (timeCurrent - timePrevious) * 0.001;
		}
	}
}